<!doctype html>
<html lang="en-US">
  <head>
    <link href="/assets/index.css" rel="stylesheet" type="text/css" />
    <script crossorigin="anonymous" src="/test-harness.js"></script>
    <script crossorigin="anonymous" src="/test-page-object.js"></script>
  </head>
  <body>
    <main id="webchat"></main>
    <script>
      const { searchParams } = new URL(location.href);
      const variant = searchParams.get('variant') || 'minimal';

      function loadScript(src) {
        return new Promise((resolve, reject) => {
          const scriptElement = document.createElement('script');

          scriptElement.setAttribute('crossorigin', 'anonymous');
          scriptElement.setAttribute('src', src);

          scriptElement.addEventListener('error', reject);
          scriptElement.addEventListener('load', resolve);

          document.head.append(scriptElement);
        });
      }

      run(async function () {
        const bundleName =
          variant === 'full' ? 'webchat.js' : variant === 'full-es5' ? 'webchat-es5.js' : 'webchat-minimal.js';

        await loadScript(`/__dist__/${bundleName}`);

        const { WebChat } = window;

        const metaMap = new Map(
          Array.from(document.querySelectorAll('meta'))
            .filter(element => element.name.startsWith('botframework-webchat'))
            .map(element => [element.name, element.getAttribute('content')])
        );

        // THEN: It should have `<meta name="botframework-webchat:api">`.
        expect(metaMap.has('botframework-webchat:api')).toBe(true);
        expect(metaMap.get('botframework-webchat:api')).toEqual(expect.stringContaining('build-tool=tsup'));
        expect(metaMap.get('botframework-webchat:api')).toEqual(expect.stringContaining('module-format='));
        expect(metaMap.get('botframework-webchat:api')).toEqual(expect.stringContaining('version='));
        expect(metaMap.get('botframework-webchat:api:version')).toEqual(expect.stringMatching(/^\d+\.\d+\.\d+($|-)/u));

        // THEN: It should have `<meta name="botframework-webchat">`.
        expect(metaMap.has('botframework-webchat')).toBe(true);
        expect(metaMap.get('botframework-webchat')).toEqual(expect.stringContaining('build-tool=tsup'));
        expect(metaMap.get('botframework-webchat')).toEqual(expect.stringContaining('module-format=global'));
        expect(metaMap.get('botframework-webchat')).toEqual(expect.stringContaining(`variant=${variant}`));
        expect(metaMap.get('botframework-webchat')).toEqual(expect.stringContaining('version='));
        expect(metaMap.get('botframework-webchat:version')).toEqual(expect.stringMatching(/^\d+\.\d+\.\d+($|-)/u));

        // THEN: It should have `<meta name="botframework-webchat:component">`.
        expect(metaMap.has('botframework-webchat:component')).toBe(true);
        expect(metaMap.get('botframework-webchat:component')).toEqual(expect.stringContaining('build-tool=tsup'));
        expect(metaMap.get('botframework-webchat:component')).toEqual(expect.stringContaining('module-format='));
        expect(metaMap.get('botframework-webchat:component')).toEqual(expect.stringContaining('version='));
        expect(metaMap.get('botframework-webchat:component:version')).toEqual(expect.stringMatching(/^\d+\.\d+\.\d+($|-)/u));

        // THEN: It should have `<meta name="botframework-webchat:core">`.
        expect(metaMap.has('botframework-webchat:core')).toBe(true);
        expect(metaMap.get('botframework-webchat:core')).toEqual(expect.stringContaining('build-tool=tsup'));
        expect(metaMap.get('botframework-webchat:core')).toEqual(expect.stringContaining('module-format='));
        expect(metaMap.get('botframework-webchat:core')).toEqual(expect.stringContaining('version='));
        expect(metaMap.get('botframework-webchat:core:version')).toEqual(expect.stringMatching(/^\d+\.\d+\.\d+($|-)/u));

        // THEN: `window.WebChat` should be a plain object.
        expect(typeof WebChat).toBe('object');

        // THEN: It should have "ReactWebChat".
        expect(WebChat).toHaveProperty('ReactWebChat', expect.any(Function));

        // THEN: It should have bits from "core" package.
        expect(WebChat).toHaveProperty('Constants', expect.any(Object));

        // THEN: It should have bits from "api" package.
        expect(WebChat).toHaveProperty('concatMiddleware', expect.any(Function));

        // THEN: It should have bits from "api/decorator" package.
        expect(WebChat).toHaveProperty('decorator', expect.any(Object));
        expect(WebChat).toHaveProperty('decorator.ActivityGroupingDecorator', expect.any(Object));

        // THEN: It should have bits from "api/middleware" package.
        expect(WebChat).toHaveProperty('middleware', expect.any(Object));
        expect(WebChat).toHaveProperty('middleware.activityComponent', expect.any(Function));

        // THEN: It should have bits from "component" package.
        expect(WebChat).toHaveProperty('Components', expect.any(Object));
        expect(WebChat).toHaveProperty('Components.BasicWebChat', expect.any(Object));

        // THEN: It should have bits from "component/decorator" package.
        expect(WebChat).toHaveProperty('decorator.BorderFlair', expect.any(Object));

        // THEN: It should have bits from "bundle/minimal" package.
        expect(WebChat).toHaveProperty('createBrowserWebSpeechPonyfillFactory', expect.any(Function));

        if (variant === 'full' || variant === 'full-es5') {
          // THEN: It should have bits from "bundle/full" package.
          expect(WebChat).toHaveProperty('Components.AdaptiveCardContent', expect.any(Object));
        } else {
          // THEN: It should not have bits from "bundle/full" package.
          expect(WebChat.Components.AdaptiveCardContent).toBeUndefined();
        }

        // THEN: `buildInfo.buildTool` should be "tsup".
        expect(WebChat).toHaveProperty('buildInfo.buildTool', 'tsup');

        // THEN: `buildInfo.moduleFromat` should be "global".
        expect(WebChat).toHaveProperty('buildInfo.moduleFormat', 'global'); // Bundle

        // THEN: `buildInfo.variant` should match.
        expect(WebChat).toHaveProperty('buildInfo.variant', variant);
      });
    </script>
  </body>
</html>
